package com.castle.fortress.admin.form.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.castle.fortress.admin.core.annotation.CastleLog;
import com.castle.fortress.admin.form.dto.FormDataDto;
import com.castle.fortress.admin.form.dto.QueryConditionDto;
import com.castle.fortress.admin.form.entity.FormConfigEntity;
import com.castle.fortress.admin.form.service.FormConfigService;
import com.castle.fortress.admin.form.service.FormDataService;
import com.castle.fortress.admin.form.service.FormModelService;
import com.castle.fortress.admin.utils.ExcelUtils;
import com.castle.fortress.admin.utils.WebUtil;
import com.castle.fortress.common.entity.DynamicExcelEntity;
import com.castle.fortress.common.entity.RespBody;
import com.castle.fortress.common.enums.OperationTypeEnum;
import com.castle.fortress.common.exception.BizException;
import com.castle.fortress.common.respcode.BizErrorCode;
import com.castle.fortress.common.respcode.GlobalRespCode;
import com.castle.fortress.common.utils.CommonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;

/**
 * 表单管理 控制器
 *
 * @author castle
 * @since 2021-11-10
 */
@Api(tags="表单管理控制器")
@Controller
public class FormManageController {
    @Autowired
    private FormDataService formDataService;
    @Autowired
    private FormModelService formModelService;
    @Autowired
    private FormConfigService formConfigService;

    /**
     * 数据沉淀
     * @param formDataDto 表模型
     * @return
     */
    @CastleLog(operLocation = "沉淀数据", operType = OperationTypeEnum.INSERT)
    @ApiOperation("沉淀数据")
    @PostMapping("/formManage/saveData")
    @ResponseBody
    public RespBody<String> saveData(@RequestBody FormDataDto formDataDto, HttpServletRequest request){
        if(CommonUtil.verifyParamNull(formDataDto,formDataDto.getTbId(),formDataDto.getFormData())){
            throw new BizException(GlobalRespCode.PARAM_MISSED);
        }
        FormConfigEntity configEntity = formConfigService.getById(formDataDto.getTbId());
        if(configEntity == null){
            throw new BizException(GlobalRespCode.UNAUTHORIZED);
        }
        //校验访问白名单
        boolean invokeFlag = true;
        String ipList = configEntity.getWhiteList();
        if(StrUtil.isEmpty(ipList)||(ipList.indexOf("*.*.*.*")==-1)){
            String ip = WebUtil.getIpAddress(request);
            if(!WebUtil.internalIp(ip)&&ipList.indexOf(ip)==-1){
                invokeFlag= false;
            }
        }
        if(!invokeFlag){
            throw new BizException(BizErrorCode.WHITE_IP_ERROR);
        }
        //校验表名是否存在
        if(!formModelService.isExistTable("castle_form"+formDataDto.getTbId())){
            throw new BizException(GlobalRespCode.UNAUTHORIZED);
        }
        formDataService.saveData(formDataDto.getTbId(),"castle_form"+formDataDto.getTbId(),formDataDto.getFormData());
        return RespBody.data("保存成功");
    }

    /**
     * 数据分页展示
     * @param queryConditionDto 查询条件
     * @return
     */
    @CastleLog(operLocation = "表单管理数据分页展示", operType = OperationTypeEnum.QUERY)
    @ApiOperation("数据分页展示")
    @GetMapping("/formManage/pageData")
    @ResponseBody
    public RespBody<IPage<Map<String, Object>>> pageData(QueryConditionDto queryConditionDto){
        if(CommonUtil.verifyParamNull(queryConditionDto,queryConditionDto.getTbId())){
            throw new BizException(GlobalRespCode.PARAM_MISSED);
        }
        queryConditionDto.setTbId(queryConditionDto.getTbId());
        return RespBody.data(formDataService.queryPageData(queryConditionDto));
    }

    /**
     * 数据详情
     * @param id 表单配置管理id
     * @return
     */
    @CastleLog(operLocation = "表单管理数据详情", operType = OperationTypeEnum.QUERY)
    @ApiOperation("数据详情")
    @GetMapping("/formManage/info")
    @ResponseBody
    public RespBody<Map<String, Object>> infoData(@RequestParam String tbId, @RequestParam String id){
        if(CommonUtil.verifyParamNull(tbId,id)){
            throw new BizException(GlobalRespCode.PARAM_MISSED);
        }
        return RespBody.data(formDataService.queryById(tbId,id));
    }

    /**
     * 数据批量删除
     * @param map
     * key: List<Long> ids 要删除的记录id集合
     *      String tbId 表id
     * @return
     */
    @CastleLog(operLocation = "表单管理数据批量删除", operType = OperationTypeEnum.DELETE)
    @ApiOperation("数据批量删除")
    @PostMapping("/formManage/deleteBatch")
    @ResponseBody
    public RespBody<String> deleteBatchData(@RequestBody Map<String,Object> map){
        if(CommonUtil.verifyParamNull(map,map.get("tbId"),map.get("ids"))){
            throw new BizException(GlobalRespCode.PARAM_MISSED);
        }
        List<Long> ids = null;
        try {
            ids = (List<Long>) map.get("ids");
            if(ids==null || ids.isEmpty()){
                throw new BizException(GlobalRespCode.PARAM_MISSED);
            }
        } catch (Exception e) {
            throw new BizException(GlobalRespCode.PARAM_MISSED);
        }
        if(formDataService.removeByIds(map.get("tbId").toString(),ids)) {
            return RespBody.data("保存成功");
        }else{
            return RespBody.fail(GlobalRespCode.OPERATE_ERROR);
        }
    }

    /**
     * 动态表头导出 依据展示的字段导出对应报表
     * @param dynamicExcelEntity
     * @param response
     * @throws Exception
     */
    @CastleLog(operLocation = "表单管理数据导出", operType = OperationTypeEnum.EXPORT)
    @PostMapping("/formManage/exportDynamic")
    @ApiOperation("动态表头导出，依据展示的字段导出对应报表")
    public void exportDynamic(@RequestBody DynamicExcelEntity<QueryConditionDto> dynamicExcelEntity, HttpServletResponse response) throws Exception {
        List<Map<String, Object>> list = formDataService.queryListData(dynamicExcelEntity.getDto());
        //字典、枚举、接口、json常量等转义后的列表数据 根据实际情况初始化该对象，null为list数据直接导出
        List<List<Object>> dataList = null;
        /**
         * 根据实际情况初始化dataList,可参照 com.castle.fortress.admin.system.controller.TmpDemoController类中方法：exportDynamic
         */
        ExcelUtils.exportFormDynamic(response,dynamicExcelEntity.getFileName()+".xlsx",null,list,dynamicExcelEntity.getHeaderList(),dataList);
    }

    /**
     * 获取验证码
     * @param map
     * key: phone_sms 获取验证码的手机号
     *      String tbId 表id
     * @return
     */
    @CastleLog(operLocation = "表单管理获取验证码", operType = OperationTypeEnum.OTHER)
    @ApiOperation("获取验证码")
    @PostMapping("/formManage/getCode")
    @ResponseBody
    public RespBody<String> getCode(@RequestBody Map<String,Object> map){
        if(formDataService.getCode(map)) {
            return RespBody.data("发送成功");
        }else{
            return RespBody.fail(GlobalRespCode.OPERATE_ERROR);
        }
    }


}
